package com.example.forumsystem.controller;

import com.example.forumsystem.common.AppResult;
import com.example.forumsystem.common.ResultCode;
import com.example.forumsystem.config.AppConfig;
import com.example.forumsystem.exception.ApplicationException;
import com.example.forumsystem.model.User;
import com.example.forumsystem.services.IUserService;
import com.example.forumsystem.utils.MD5Util;
import com.example.forumsystem.utils.StringUtil;
import com.example.forumsystem.utils.UUIDUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;

import static com.example.forumsystem.config.AppConfig.USER_SESSION;

@Slf4j
@Api(tags = "用户相关接口")
@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private IUserService userService;

    /**
     * 用户注册
     * @param userName 用户名
     * @param nickName 昵称
     * @param password 密码
     * @param passwordRepeat    确认密码
     * @return 成功/失败(失败原因)
     */
    @ApiOperation("用户注册")
    @PostMapping("/register")
    private AppResult register(@ApiParam("用户名") @RequestParam("userName") @NonNull String userName,
                               @ApiParam("昵称") @RequestParam("nickName")  @NonNull String nickName,
                               @ApiParam("密码") @RequestParam("password") @NonNull String password,
                               @ApiParam("确认密码") @RequestParam("passwordRepeat") @NonNull String passwordRepeat) {

//        // 传统的非空校验
//        if(StringUtil.isEmpty(userName) || StringUtil.isEmpty(nickName)
//            || StringUtil.isEmpty(password) || StringUtil.isEmpty(passwordRepeat)) {
//            return AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE);
//        }
        // 校验两次密码是否相同
        if(!password.equals(passwordRepeat)) {
            return AppResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME);
        }
        // 处理密码
        // 盐
        String salt = UUIDUtil.salt32();
        // 密文
        String encrypt = MD5Util.md5Salt(password,salt);

        // 构造用户
        User user = new User();
        user.setUserName(userName);
        user.setPassword(encrypt);
        user.setNickName(nickName);
        user.setSalt(salt);
        // 调用 service 层
        userService.createNormalUser(user);

        return AppResult.success();
    }



    @PostMapping("/login")
    @ApiOperation("用户登入")
    public AppResult login(HttpServletRequest request,
//                           @ApiParam("用户名") @RequestParam("userName") @NonNull String userName,
                           @ApiParam("用户名") @RequestParam("userName") @NonNull String userName,
                           @ApiParam("密码")  @RequestParam("password") @NonNull String password) {
        // 传入service 校验信息
        User user = userService.login(userName,password);
        if(user == null) {
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN));
        }
        // 存入session
        HttpSession session = request.getSession(true);
        session.setAttribute(AppConfig.USER_SESSION,user);
        return AppResult.success();
    }

    @ApiOperation("获取用户信息")
    @GetMapping("/info")
    public AppResult<User> getUserInfo(HttpServletRequest request,
                                       @ApiParam("用户ID")  @RequestParam(value = "id" ,required = false) Long id) {
        User user = null;
        // 根据id进行校验
        if(id == null) {
            // 从session中拿取用户信息
            HttpSession session = request.getSession();
            // 校验session的合法性
            if(session == null || session.getAttribute(AppConfig.USER_SESSION) == null) {
                // session不存在,抛出异常
                throw new ApplicationException(AppResult.failed(ResultCode.FAILED_FORBIDDEN));
            }
            user = (User) session.getAttribute(AppConfig.USER_SESSION);
        }else {
            // 根据用户id获取用户信息
            user = userService.selectById(id);
        }
        // 最后的校验
        if(user == null) {
            // 用户不存在
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_FORBIDDEN));
        }
        return AppResult.success(user);
    }
    @ApiOperation("退出登入")
    @GetMapping("/logout")
    public AppResult logou(HttpServletRequest request) {
        HttpSession session = request.getSession();
        // 销毁session
        if(session != null) {
            session.invalidate();
        }
        return AppResult.success();
    }

    @ApiOperation("修改个⼈信息")
    @PostMapping("/modifyInfo")
    public AppResult modifyInfo(HttpServletRequest request,
                                @ApiParam("用户名(用于登入)") @RequestParam(value = "username",required = false)  String userName,
                                @ApiParam("昵称") @RequestParam(value = "nickName",required = false) String nickName,
                                @ApiParam("性别") @RequestParam(value = "gender",required = false) Byte gender,
                                @ApiParam("邮箱") @RequestParam(value = "email",required = false) String email,
                                @ApiParam("电话") @RequestParam(value = "phoneNum",required = false) String phoneNum,
                                @ApiParam("个人简介") @RequestParam(value = "remark",required = false) String remark) {
        log.info("nickName: " + nickName);
        // 进行参数校验,如果全为空就抛异常
        if(StringUtil.isEmpty(userName) && StringUtil.isEmpty(nickName)
                && StringUtil.isEmpty(email) && StringUtil.isEmpty(phoneNum)
                && StringUtil.isEmpty(remark) && gender == null) {
            throw new ApplicationException(AppResult.failed("请输入需要修改的值"));
        }

        // 获取user对象
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);

        // 校验用户是否存在
        if(user == null) {
            // 打印日志
            log.info(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            // 返回异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }

        // 构建修改对象
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setUserName(userName);
        updateUser.setNickName(nickName);
        updateUser.setGender(gender);
        updateUser.setEmail(email);
        updateUser.setPhoneNum(phoneNum);
        updateUser.setRemark(remark);
        userService.modifyInfo(updateUser);
//        // 更新session
//        session.setAttribute(AppConfig.USER_SESSION,updateUser);
//        session.invalidate();
        return AppResult.success();
    }

    @PostMapping("/modifyPwd")
    @ApiOperation("修改密码")
    public AppResult modifyPwd(HttpServletRequest request,
                               @ApiParam("原密码") @RequestParam("oldPassword") @NonNull String oldPassword,
                               @ApiParam("新密码") @RequestParam("newPassword") @NonNull String newPassword,
                               @ApiParam("确认密码") @RequestParam("passwordRepeat") @NonNull String passwordRepeat) {

        // 校验两次密码输入是否相同
        if(!newPassword.equals(passwordRepeat)) {
            // 打印日志
            log.info(ResultCode.FAILED_TWO_PWD_NOT_SAME.toString());
            // 返回异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME));
        }

        // 从session获取用户
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);

        // 校验用户权限
        if(user == null || user.getId() <= 0 || user.getState() == 1 || user.getDeleteState() == 1) {
            // 打印日志
            log.info(ResultCode.FAILED_USER_UNAUTHORIZED.toString());
            // 返回异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_UNAUTHORIZED));
        }
        // 调用service修改密码
        userService.modifyPwd(user.getId(),oldPassword,newPassword);

        // 销毁session,让用户重新登入
        if(session != null) {
            session.invalidate();
        }

        return AppResult.success();
    }


    @ApiOperation("修改头像")
    @PostMapping("/upload")
    public AppResult upload(@ApiParam("头像文件") @RequestParam("file") @NonNull MultipartFile file,
                            @ApiParam("用户id") @RequestParam("userId") @NonNull Long userId, HttpServletRequest request) {

        // 获取当前登入的用户信息
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(USER_SESSION);
        System.out.println(user.toString());
        // 校验用户权限
        if(user == null || user.getId() <= 0 || user.getState() == 1 || user.getDeleteState() == 1) {
            // 打印日志
            log.info(ResultCode.FAILED_USER_UNAUTHORIZED.toString());
            // 返回异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_UNAUTHORIZED));
        }

        // 获取上传的文件名字
        String originalFilename = file.getOriginalFilename();

        // 生成时间戳, 再拼接上切割出来的后缀名
        String newName = System.currentTimeMillis() + originalFilename.substring(originalFilename.lastIndexOf("."));

        // 将新的文件存入数据库中
        File saveFile = new File("D:/git/forum/forumSystem/src/main/resources/static/image/",newName);
        // 创建图片
        try {
            file.transferTo(saveFile);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 修改用户的头像地址
        userService.upload(userId,newName);
        return  AppResult.success();
    }

}
